<?php

class QGlobal
{   
    private $varName = '';
    private $varValue = null;
    private $methodName = null;
    private static $isValid = false;
    private $QXC;

    function __construct($qxc)
    {
        $this->QXC = $qxc;
    }

    protected function __get($name)
    {
        $methods = array
            (
            'POST',
            'GET',
            'FILES',
            'COOKIE',
            'SESSION',
            'SERVER'
        );

        $name = strtoupper($name);

        if (isset($name) && in_array($name, $methods))
        {
            $newObj = clone $this;
            $newObj->methodName = $name;

            return $newObj;
        }

        throw new QException("Request method {$name} not defined");
    }

    /**
     * @return string
     */
    public function __toString()
    {
        return $this->ToString();
    }

    /**
     * @return QGlobal
     */
    public function Post($name = '')
    {
        $newObj = clone $this;
        $newObj->methodName = "POST";
        $newObj->varName = $name;
        $newObj->varValue = $this->QXC->getGlobal($name, 'POST');

        return $newObj;
    }

    /**
     * @param name[optional]
     * @return QGlobal
     */
    public function Get($name = '')
    {
        $newObj = clone $this;
        $newObj->methodName = "GET";
        $newObj->varValue = $this->QXC->getGlobal($name, 'GET');

        return $newObj;
    }

    /**
     * @param name[optional]
     * @return QGlobal
     */
    public function Server($name = '')
    {
        $newObj = clone $this;
        $newObj->methodName = "SERVER";
        $newObj->varValue = $this->QXC->getGlobal($name, 'SERVER');

        return $newObj;
    }

    /**
     * @return QGlobal
     */
    public function Cookie($name)
    {
        $newObj = clone $this;
        $newObj->methodName = "COOKIE";
        $newObj->varValue = $this->QXC->getGlobal($name, 'COOKIE');

        return $newObj;
    }

    /**
     * @return QGlobal
     */
    public function Session($name, $value = "")
    {
        if (empty($value))
        {
            $newObj = clone $this;
            $newObj->methodName = "SESSION";
            $newObj->varValue = $this->QXC->getGlobal($name, 'SESSION');

            return $newObj;
        }
        else
        {
            $_SESSION[$name] = $value;

            return $this;
        }
    }

    /**
     * @return QGlobal
     */
    public function Files($name = "", $var = "")
    {
        $newObj = clone $this;
        $newObj->methodName = "FILES";
        $newObj->varValue = $this->QXC->getGlobal($name, 'FILES');


        //        if (!empty ($name))
        //        {
        //            if (!empty ($var))
        //            {
        //                return $newObj->tempVar[$var];
        //            }
        //
        //            return $newObj->tempVar;
        //        }

        return $newObj;
    }

    /**
     * Move uploaded file to new location
     * @param New folder
     * @return bool
     */
    public function Move($path)
    {
        if($this->methodName != 'FILES')
        {
            die('You can call IsUploaded() for $_FILES method only');
        }

        move_uploaded_file($this->varValue['tmp_name'], $path);

        return true;
    }

    /**
     * TODO Optimize algorithm
     * @param name[optional]
     * @return object|array
     */
    public function Validate($pattern, $message = null)
    {
        if (empty ($this->methodName))
        {
            throw new QException("You must use 'Validate' method with an request method");
        }

        $args = func_get_args();

        if (is_string($pattern))
        {
            if(is_callable($pattern))
            {
                return call_user_func($pattern, $this->varValue);
            }

            if($pattern{0} != "/")
            {
                $pattern = "/{$pattern}/";
            }

            if (preg_match($pattern, $this->varValue))
            {
                self::$isValid = true;
            }
            else
            {
                if(!is_null($message))
                {
                    $this->QXC->setGlobal($this->varName, array($pattern, $message), 'VALIDATION');
                }

                self::$isValid = false;
            }

            return self::$isValid;
        }
        else
        {
            foreach ($args as $val)
            {
                $key = (string)$val[0];
                $pattern = (string)$val[1];

                $var = $this->QXC->getGlobal($key, $this->methodName);

                if($pattern[0] != "/")
                {
                    $pattern = "/^{$pattern}$/";
                }

                if (!preg_match($pattern, $var))
                {
                    $this->QXC->setGlobal($key, $val[2], 'ERRORS');
                }
            }

            return $this;
        }
    }

    public function IsValid()
    {
        return self::$isValid;
    }

    /**
     * @return QGlobal
     */
    public function Clean()
    {
        if (empty($this->varValue) && !empty($this->methodName))
        {
            $arr = $this->QXC->getGlobal(null, $this->methodName);

            foreach ($arr as $key => $val)
            {
                if (is_string($val))
                {
                    $this->QXC->setGlobal($key, $this->cleanString($val), $this->methodName);
                }
                else
                {
                // TODO Write cleaner code for array
                }
            }
        }
        else
        {
            if (is_string($this->varValue))
            {
                $this->varValue = $this->cleanString($this->varValue);
            }
            else
            {
            // TODO Write cleaner code for array
            }
        }

        return $this;
    }

    /**
     * @return bool
     */
    public function IsEqual($string)
    {
        if(!empty ($this->varValue) && $this->varValue == $string)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * @return bool
     */
    public function IsUploaded()
    {
        if($this->methodName != 'FILES')
        {
            die('You can call IsUploaded() for $_FILES method only');
        }

        if(!empty ($this->varValue) && is_uploaded_file($this->varValue['tmp_name']))
        {
            return true;
        }

        return false;
    }

    /**
     * @return string
     */
    public function Trim($chars = "")
    {
        return trim($this->ToString());
    }

    /**
     * @return bool
     */
    public function IsEmpty()
    {
        if(empty($this->varValue))
        {
            return true;
        }

        return false;
    }

    /**
     * @return int
     */
    public function ToInt()
    {
        return (int)$this->varValue;
    }

    /**
     * @return string
     */
    public function ToString()
    {
        return (string)$this->varValue;
    }

    /**
     * @return mixed
     */
    public function ToArray($key = '')
    {
        if (!empty ($this->varValue))
        {
            $arr = $this->varValue;
        }
        else if (!empty ($this->methodName))
        {
            $arr = $this->QXC->getGlobal(null, $this->methodName);
        }
        else
        {
            throw new QException("Not implemented");
        }

        return empty($key) ? $arr : $arr[$key];
    }

    private function cleanString($input)
    {
        $input = htmlentities($input);

        if(get_magic_quotes_gpc())
        {
            $input = stripslashes($input);
        }

        $input = strip_tags($input);

        return trim($input);
    }

    // Response
    public function Redirect($url = "")
    {
        if (empty ($url))
        {
            $url = WEB_URL;
        }
        else if (!preg_match("/^http\:\/\//", $url))
            {
                $url = WEB_URL . "/{$url}";
            }

        if (!headers_sent())
        {
            header("Location: {$url}");
        }

        die($url);
    }

    public function Header($key, $value = null)
    {
        if(!is_null($value))
        {
            header("{$key}: {$value}");
        }
        else
        {
            header($key);
        }
    }
}